package com.daffodil.workable.factory;

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.ConcurrentHashMap;

import org.flowable.common.engine.impl.el.DefaultExpressionManager;
import org.springframework.stereotype.Component;

import com.daffodil.workable.exception.WorkableStrategyClassNotRegisterException;
import com.daffodil.workable.factory.strategy.DataFilterWorkableStrategy;
import com.daffodil.workable.factory.strategy.EmailWorkableStrategy;
import com.daffodil.workable.factory.strategy.EndWorkableStrategy;
import com.daffodil.workable.factory.strategy.HttpWorkableStrategy;
import com.daffodil.workable.factory.strategy.MobileWorkableStrategy;
import com.daffodil.workable.factory.strategy.QiweiWorkableStrategy;
import com.daffodil.workable.factory.strategy.StartWorkableStrategy;
import com.daffodil.workable.factory.strategy.WorkableStrategy;

import lombok.extern.slf4j.Slf4j;

/**
 * -默认任务工作流策略工厂
 * @author yweijian
 * @date 2022年4月8日
 * @version 1.0
 * @description
 */
@Slf4j
@SuppressWarnings({"rawtypes", "unchecked"})
@Component
public class DefaultWorkableFactory implements WorkableFactory {

    private final ConcurrentHashMap<String, Class> workableStrategyClassMap = new ConcurrentHashMap<>();

    private DefaultExpressionManager expressionManager;
    
    /**
     * -默认注册工厂
     */
    public DefaultWorkableFactory() {
        this.expressionManager = new DefaultExpressionManager();
        //开始节点
        this.register("start-node", StartWorkableStrategy.class);
        //结束节点
        this.register("end-node", EndWorkableStrategy.class);
        //Http请求节点
        this.register("http-request", HttpWorkableStrategy.class);
        //电话告警
        this.register("mobile-notice", MobileWorkableStrategy.class);
        //邮箱告警
        this.register("email-notice", EmailWorkableStrategy.class);
        //企业微信告警
        this.register("qiwei-notice", QiweiWorkableStrategy.class);
        this.register("data-filter", DataFilterWorkableStrategy.class);
        
    }

    public DefaultWorkableFactory(String modelId, Class clazz) {
        this.expressionManager = new DefaultExpressionManager();
        this.register(modelId, clazz);
    }

    public void register(String modelId, Class clazz) {
        this.workableStrategyClassMap.put(modelId, clazz);
        if(log.isInfoEnabled()) {
            log.info( "Registering workable strategy modelId={} -> {}", modelId, clazz.getName());
        }
    }

    public Class getWorkableStrategyClass(String modelId) {
        Class clazz = workableStrategyClassMap.get(modelId);
        if(clazz == null) {
            throw new WorkableStrategyClassNotRegisterException(40001, new Object[] {modelId});
        }
        return clazz;
    }

    @Override
    public WorkableStrategy createWorkableStrategy(String modelId) {
        Class clazz = this.getWorkableStrategyClass(modelId);
        WorkableStrategy strategy = null;
        try {
            strategy = (WorkableStrategy) clazz.getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
                | NoSuchMethodException | SecurityException e) {
            log.error(e.getMessage(), e);
            throw new WorkableStrategyClassNotRegisterException(40002, new Object[] {modelId});
        }
        return strategy;
    }

    public DefaultExpressionManager getExpressionManager() {
        return expressionManager;
    }

}
